package com.alvin.abp.service;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alvin.abp.domain.AlvinUser;
import com.alvin.abp.domain.Bonus;
import com.alvin.abp.domain.DepartType;
import com.alvin.abp.domain.Point;
import com.alvin.abp.domain.Rule;
import com.alvin.abp.domain.Status;

@Service(value="bonusService")
public class BonusService {

	private NamedParameterJdbcTemplate jdbcTemplate;
	
	@Autowired
	private UserService userService;
	@Autowired
	private RuleService ruleService;
	
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
	}
	
	@Transactional
	public void addBonus(Bonus bonus){
		String sql = "INSERT INTO T_RECORD (`MEMBER_ID`, `BALANCE`, `POINT`, `RULE_ID`, `VISIBLE`, `INSERT_TIME`) VALUES (?, ?, ?, ?, 1, ?)";
		AlvinUser user = bonus.getUser();
		int point = 0;
		long ruleId = bonus.getRule().getId();
		if(ruleId == 1l) {
			Point pointObj = this.readPoint(bonus.getCode());
			point = pointObj.getPoint();
		}else{
			Rule rule = ruleService.readRuleById(bonus.getRule().getId());
			point = rule.getPoint();
		}
		
		BigDecimal base = user.getBalance();
		BigDecimal balance = base.add(new BigDecimal(point));
		user.setBalance(balance);
		jdbcTemplate.getJdbcOperations().update(sql, new Object[]{user.getId(), balance, point, ruleId, new Date()});
		userService.updateBalance(user);
	}
	
	public Point readPoint(String code) {
		Point point;
		try{
			String sql = "SELECT `POINT`, QR.`STATE`, G.DEPARTMENT_ID, G.INSERT_TIME FROM MARCHANDISE M LEFT JOIN GOODS G ON G.MARCHANDISE_ID = M.ID  LEFT JOIN QR_GOODS_CODE QR ON G.QR_CODE_ID = QR.ID WHERE QR.I_CODE = ? ORDER BY INSERT_TIME DESC LIMIT 1;";
			point = (Point)jdbcTemplate.getJdbcOperations().queryForObject(sql, new Object[]{code}, new PointRowMapper());
		} catch (EmptyResultDataAccessException ex) {
			return null;
		}
		return point;
		 
	}
	
	public boolean checkGoodStatus(String code) {
		String sql = "SELECT IF(G.`STATE`='"+Status.HAS_OUT+"' AND TY.`NAME`='"+DepartType.SD+"', 1, 0) FROM GOODS G LEFT JOIN QR_GOODS_CODE QR ON G.QR_CODE_ID = QR.ID LEFT JOIN DEPARTMENT D ON G.DEPARTMENT_ID = D.ID LEFT JOIN DEPARTMENT_TYPE TY ON D.TYPE_ID = TY.ID WHERE QR.I_CODE=? ORDER BY G.INSERT_TIME DESC LIMIT 1;";
		return (jdbcTemplate.getJdbcOperations().queryForInt(sql, new String[] {code})==1)?true:false;
	}
	
    static class PointRowMapper implements RowMapper<Point> {

        public Point mapRow(ResultSet rs, int rowNum) throws SQLException {

        	Point point = new Point();
        	point.setQrStatus(Status.valueFor(rs.getString("STATE")));//REMIND: Only contains the qr status.
        	point.setPoint(rs.getInt("POINT"));
        	
        	return point;

        }

    }	
	
}
